using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

using SlimDX;
using SlimDX.Direct3D9;
using SlimDX.Windows;

using miciv.Rendering;
using miciv.Geometry;

namespace miciv
{
    public class TextureColorRectangle : Frame, IDiffuse, IAlbedoTexture
    {
        protected Color4 m_f4Diffuse;
        protected TextureManager.ManagedTexture m_textureAlbedo;
        protected IShape m_shape;

        public TextureColorRectangle(CoreContext _coreContext, string _strID)
            : base(_coreContext, _strID)
        {
        }

        public TextureColorRectangle(CoreContext _coreContext, string _strID, Frame _frmParent)
            : base(_coreContext, _strID, _frmParent)
        {
        }

        override protected void InternalInitialize(CoreContext _coreContext, string _strID)
        {
            base.InternalInitialize(_coreContext, _strID);
            this.AutoResize = false;
            this.Diffuse = new Color4(1.0f, 1.0f, 1.0f, 1.0f);
            this.m_renderer = this.m_coreContext.GetData<RendererManager>("RendererManager").GetByVertexDefinition("TextureDiffuseVertexDefinition", this);
        }

        override public Frame Clone(Frame _frmParent, string _strID)
        {
            Frame frame = new TextureColorRectangle(this.m_coreContext, this.m_strID + _strID, _frmParent);
            frame.Copy(this);
            foreach (Frame child in this.m_lstChildren)
            {
                child.Clone(frame);
            }
            return frame;
        }

        override public Frame Clone(Frame _frmParent)
        {
            return this.Clone(_frmParent, "");
        }

        override public void Copy(Frame _frame)
        {
            base.Copy(_frame);
            TextureColorRectangle tcr = _frame as TextureColorRectangle;
            this.Albedo = tcr.Albedo;
            this.AutoResize = tcr.AutoResize;
            this.Diffuse = tcr.Diffuse;
        }

        override public void UpdateData(float _deltaTime)
        {
            base.UpdateData(_deltaTime);
            if (false != this.NeedUpdate)
            {
                if (false != this.NeedUpdateFromDataSource)
                {
                    foreach (DictionaryEntry de in this.m_htblParameters)
                    {
                        string strDestination = de.Value as string;
                        switch (strDestination)
                        {
                            case "albedo":
                                this.Albedo = this.m_dataSource.GetData<TextureManager.ManagedTexture>(this.m_sDataSourceIndex, de.Key as string);
                                break;
                        }
                    }
                }

                if (false != this.m_bDirty)
                {
                    this.BuildShapeVertexFeeder();
                    this.m_bDirty = false;
                }
            }
        }

        override public Vector2 Size
        {
            get
            {
                return this.m_f2Size;
            }
            set
            {
                if (false == this.AutoResize)
                {
                    base.Size = value;
                }
            }
        }

        override public bool AutoResize
        {
            set
            {
                this.m_bAutoResize = value;
                if ((false != this.m_bAutoResize) && (null != this.Albedo))
                {
                    // temporally disable auto resize flag so that Size property works
                    this.m_bAutoResize = false;
                    this.Size = new Vector2(this.Albedo.Info.Width, this.Albedo.Info.Height);
                    // then lock size back
                    this.m_bAutoResize = true;
                }
            }
        }

        protected bool BuildShapeVertexFeeder()
        {
            if (null == this.m_shape)
            {
                this.m_shape = this.m_coreContext.GetData<ShapeManager>("ShapeManager").Create("rectangle");
                this.m_shape.VertexDefinition = this.m_coreContext.GetData<VertexDefinitionManager>("VertexDefinitionManager").Get("TextureDiffuseVertexDefinition");
                this.m_shape.LevelOfDetail = 1;
            }
            this.m_shape.Size = new Vector3(this.Size, 0.0f);
            bool bResult = this.m_shape.Build(null);
            if (false != bResult)
            {
                if (null != this.m_vertexFeeders)
                {
                    this.Renderer.ReleaseFeeders(this.m_vertexFeeders);
                }
                this.m_vertexFeeders = this.Renderer.CreateFeeders(this.m_shape);
            }
            return ((false != bResult) && (null != this.m_vertexFeeders) && (0 < this.m_vertexFeeders.Count));
        }

        #region IColor Membres

        public Color4 Diffuse
        {
            get
            {
                return this.m_f4Diffuse;
            }
            set
            {
                this.m_f4Diffuse = value;
                this.m_bDirty = true;
            }
        }

        #endregion

        #region IAlbedoTexture Membres

        public TextureManager.ManagedTexture Albedo
        {
            get
            {
                return this.m_textureAlbedo;
            }
            set
            {
                if (value != this.m_textureAlbedo)
                {
                    this.m_textureAlbedo = value;
                    if ((false != this.AutoResize) && (null != this.m_textureAlbedo))
                    {
                        // temporally disable auto resize flag so that Size property accepts modification
                        this.AutoResize = false;
                        this.Size = new Vector2(this.m_textureAlbedo.Info.Width, this.m_textureAlbedo.Info.Height);
                        // then lock size back
                        this.AutoResize = true;
                    }
                }
            }
        }

        #endregion
    }
}
